﻿#include <iostream>
#include <vector>

#ifndef BIG_INT_H
#define BIG_INT_H

typedef std::vector<signed int> Vector;
#define M_BASE static_cast<long long int>(INT_MAX)+1
#define MAX_NUM INT_MAX

class BigInt
{
public:
	BigInt(void);
	explicit BigInt(const int&);
	explicit BigInt(const std::string&);
	~BigInt(void);
	void SetValue(const int&);
	void SetValue(const std::string&);

	BigInt operator-()const;//-a
	const BigInt operator++(int);//a++
	const BigInt& operator++();//++a
	const BigInt operator--(int);//a--
	const BigInt& operator--();//--a

	BigInt& operator+=(const BigInt&);
	BigInt& operator-=(const BigInt&);
	BigInt& operator*=(const BigInt&);
	BigInt& operator/=(const BigInt&);
	BigInt& operator%=(const BigInt&);
	BigInt& operator&=(const BigInt&);
	BigInt& operator|=(const BigInt&);

	const BigInt operator<<(const BigInt&)const;
	BigInt& operator<<=(const BigInt&);

	friend bool operator==(const BigInt&,const BigInt&);
	friend bool operator!=(const BigInt&,const BigInt&);

	bool operator>(const BigInt&)const;
	bool operator<(const BigInt&)const;
	bool operator>=(const BigInt&)const;
	bool operator<=(const BigInt&)const;

	friend BigInt pow(const BigInt&, const BigInt&);
	friend BigInt pow(const BigInt&, const int&);
	
	friend std::ostream& operator<<(std::ostream&, const BigInt&);/*Stampa in base INT_MAX + 1*/
	void slowPrint() const;/*Stampa in base 1 miliardo*/

	friend BigInt convertToAnotherBase(const BigInt&);
private:
	Vector m_value;
	bool m_sign;
	void Init(const int&);
	void Init(const std::string&);

	void subtract(const BigInt&);
	void sum(const BigInt&);
	bool isModuleSmaller(const BigInt&) const;
	bool isModuleGreater(const BigInt&) const;
	bool isModuleEqual(const BigInt&) const;
	bool isZero() const;
	
};

const BigInt operator+(const BigInt&, const BigInt&);
const BigInt operator-(const BigInt&, const BigInt&);
const BigInt operator*(const BigInt&, const BigInt&);
const BigInt operator/(const BigInt&, const BigInt&);
const BigInt operator%(const BigInt&, const BigInt&);
const BigInt operator&(const BigInt&, const BigInt&);
const BigInt operator|(const BigInt&, const BigInt&);

/*SOLO PER DEBUG E PER TRASFORMARE IN BASE DECIMALE*/
BigInt convertToAnotherBase(const BigInt&, const long long int&);
#include "BigInt.inl"

#endif

